import { getUserRoles, getUserMenus } from '@/api/system/user'
import { login, logout } from '@/api/common'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { genNonDuplicateID } from '@/utils/tools'
import { resetRouter } from '@/router'
import Cookies from 'js-cookie'
import path from 'path'

const getDefaultState = () => {
  return {
    token: getToken(),
    name: Cookies.get('name') || '',
    avatar: '',
    roleList: [],
    roleId: Cookies.get('roleId') || '',
    menuList: [],
    routerStart: '',
    authList: []
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    Cookies.set('name', name)
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_ROLE_LIST: (state, roleList) => {
    state.roleList = roleList
  },
  SET_MENU_LIST: (state, menuList) => {
    state.menuList = menuList
  },
  SET_ROLE_ID: (state, roleId) => {
    Cookies.set('roleId', roleId)
    state.roleId = roleId
  },
  SET_ROUTER_START: (state, routerStart) => {
    state.routerStart = routerStart
  },
  SET_AUTH_LIST: (state, authList) => {
    state.authList = authList
  }
}

const actions = {
  // user login
  login ({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username, password: password }).then(response => {
        const { nickname, token } = response
        commit('SET_TOKEN', token)
        commit('SET_NAME', nickname)
        setToken(token)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  getMenus ({ commit }) {
    return new Promise((resolve, reject) => {
      getUserMenus().then(res => {
        let { menuList, permissionUrlList } = res.data
        // 保留一个始终拥有的标签栏
        menuList[0].affix = true
        if (!menuList?.length) {
          reject('验证失败，请重新登录。')
        }
        const menus = filterAsyncMenu(menuList.filter(o => (o.level === 1 && o.children.length) || o.level === 2))
        // const menusList = menus.concat(LocalFixRoutes)
        const menusList = menus
        commit('SET_MENU_LIST', menusList)
        commit('SET_AUTH_LIST', permissionUrlList)
        const routerStart = getRouter(menusList)
        commit('SET_ROUTER_START', routerStart)
        resolve(routerStart)
      }).catch(error => {
        reject(error.msg)
      })
    })
  },

  // get user roles menus
  getRoleToMenu ({ commit, dispatch, state }) {
    return new Promise((resolve, reject) => {
      getUserRoles().then(res => {
        commit('SET_ROLE_LIST', res.data)
        dispatch('updateRole', state.roleId ? state.roleId : res.data[0].id)
        if (!res.data?.length) {
          reject('验证失败，请重新登录。')
        }
        resolve()
      }).catch(error => {
        reject(error.msg)
      })
    })
  },

  // 更新菜单信息
  updateRole ({ commit, state }, roleId) {
    return new Promise((resolve) => {
      const roleList = state.roleList
      const [{ id, name, menus }] = roleList.filter(o => o.id == roleId)
      commit('SET_ROLE_ID', id)
      commit('SET_NAME', name)
      // 保留一个始终拥有的标签栏
      menus[0].affix = true
      const menuList = filterAsyncMenu(menus)
      commit('SET_MENU_LIST', menuList)
      resolve(menuList)
    })
  },

  // user logout
  logout ({ commit }) {
    return new Promise((resolve, reject) => {
      logout().then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        // commit('SET_ROLE', [])
        commit('SET_NAME', '')
        commit('SET_ROLE_ID', '')
        commit('RESET_STATE')
        commit('SET_ROLE_LIST', [])
        commit('SET_MENU_LIST', [])
        resolve()
      }).catch(err => {
        reject(err)
      })
    })
  },

  // remove token
  resetToken ({ commit }) {
    return new Promise(resolve => {
      removeToken() // must remove  token  first
      commit('RESET_STATE')
      resolve()
    })
  }
}

// 获取需要重定向的url
const getRouter = (menuList) => {
  for (const menu of menuList) {
    if (menu.children && menu.children.length) {
      return menu.children[0].fullPath
    }
    return menu.fullPath
  }
}

// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncMenu (asyncRouterMap, basePath = '/', affix = false) {
  return asyncRouterMap.map((route, i) => {
    // 判断链接是否http或者https开头
    const isHttp = /^(http|https):\/\//.test(route.url)
    const tagPath = isHttp ? route.url : path.resolve(basePath, route.url || '/' + genNonDuplicateID())
    const newRoute = {
      fullPath: tagPath,
      path: tagPath,
      name: tagPath,
      meta: {
        icon: 'el-icon-' + route.icon,
        title: route.name
      }
    }
    if ((route.affix || affix) && i == 0) {
      newRoute.affix = true
    }
    if (route.children != null && route.children && route.children.length) {
      newRoute.children = filterAsyncMenu(route.children, route.url || '/', i == 0)
    }
    return newRoute
  })
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

